package at.bestsolution.efxclipse.runtime.example.photoedit.ui;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.MEDIA__DESCRIPTION;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.MEDIA__TITLE;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.PHOTO_AREA__DESCRIPTION;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.PHOTO_AREA__HEIGHT;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.PHOTO_AREA__WIDTH;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.PHOTO_AREA__X;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.PHOTO_AREA__Y;
import static at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoeditPackage.Literals.PHOTO__AREAS;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.VPos;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.IEMFValueProperty;
import at.bestsolution.efxclipse.runtime.databinding.AdapterFactory;
import at.bestsolution.efxclipse.runtime.databinding.IJFXBeanValueProperty;
import at.bestsolution.efxclipse.runtime.databinding.JFXBeanProperties;
import at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.Media;
import at.bestsolution.efxclipse.runtime.example.photoedit.model.photoedit.PhotoArea;
@SuppressWarnings("restriction")
public class MediaPropertiesView {
private WritableValue currentSelection = new WritableValue();
private TableView<PhotoArea> photoAreas;
@PostConstruct
void init(BorderPane pane) {
VBox box = new VBox();
GridPane mediaProperties = new GridPane();
EMFDataBindingContext dbc = new EMFDataBindingContext();
{
Label l = new Label("Title");
mediaProperties.add(l, 0, 0);
TextField f = new TextField();
IEMFValueProperty mProp = EMFProperties.value(MEDIA__TITLE);
IJFXBeanValueProperty tProp = JFXBeanProperties.value("text");
dbc.bindValue(
tProp.observe(f),
mProp.observeDetail(currentSelection)
);
mediaProperties.add(f, 1, 0);
GridPane.setHgrow(f, Priority.ALWAYS);
}
{
Label l = new Label("Description");
mediaProperties.add(l, 0, 1);
GridPane.setValignment(l, VPos.TOP);
TextArea area = new TextArea();
area.setPrefColumnCount(5);
mediaProperties.add(area, 1, 1);
GridPane.setHgrow(area, Priority.ALWAYS);
dbc.bindValue(EMFProperties.value(MEDIA__DESCRIPTION).observeDetail(currentSelection), JFXBeanProperties.value("text").observe(area));
}
TitledPane generalProps = new TitledPane("General Properties",mediaProperties);
box.getChildren().add(generalProps);
photoAreas = new TableView<PhotoArea>();
{
TableColumn<PhotoArea, String> col = new TableColumn<PhotoArea, String>();
col.setText("Bounds");
col.setPrefWidth(50);
{
TableColumn<PhotoArea, Double> subCol = new TableColumn<PhotoArea, Double>();
subCol.setText("x");
subCol.setPrefWidth(20);
subCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<PhotoArea,Double>, ObservableValue<Double>>() {
@Override
public ObservableValue<Double> call(final CellDataFeatures<PhotoArea, Double> param) {
return AdapterFactory.adapt(EMFProperties.value(PHOTO_AREA__X).observe(param.getValue()));
}
});
col.getColumns().add(subCol);
}
{
TableColumn<PhotoArea, Double> subCol = new TableColumn<PhotoArea, Double>();
subCol.setText("y");
subCol.setPrefWidth(20);
subCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<PhotoArea,Double>, ObservableValue<Double>>() {
@Override
public ObservableValue<Double> call(final CellDataFeatures<PhotoArea, Double> param) {
return AdapterFactory.adapt(EMFProperties.value(PHOTO_AREA__Y).observe(param.getValue()));
}
});
col.getColumns().add(subCol);
}
{
TableColumn<PhotoArea, Double> subCol = new TableColumn<PhotoArea, Double>();
subCol.setText("width");
subCol.setPrefWidth(20);
subCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<PhotoArea,Double>, ObservableValue<Double>>() {
@Override
public ObservableValue<Double> call(final CellDataFeatures<PhotoArea, Double> param) {
return AdapterFactory.adapt(EMFProperties.value(PHOTO_AREA__WIDTH).observe(param.getValue()));
}
});
col.getColumns().add(subCol);
}
{
TableColumn<PhotoArea, Double> subCol = new TableColumn<PhotoArea, Double>();
subCol.setText("heigth");
subCol.setPrefWidth(20);
subCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<PhotoArea,Double>, ObservableValue<Double>>() {
@Override
public ObservableValue<Double> call(final CellDataFeatures<PhotoArea, Double> param) {
return AdapterFactory.adapt(EMFProperties.value(PHOTO_AREA__HEIGHT).observe(param.getValue()));
}
});
col.getColumns().add(subCol);
}
photoAreas.getColumns().add(col);
}
{
TableColumn<PhotoArea, String> col = new TableColumn<PhotoArea, String>();
col.setText("Description");
col.setMaxWidth(100);
col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<PhotoArea,String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(CellDataFeatures<PhotoArea, String> param) {
//TODO We need to remove the dispose the observable created here
IObservableValue v = EMFProperties.value(PHOTO_AREA__DESCRIPTION).observe(param.getValue());
return AdapterFactory.adapt(v);
}
});
col.setCellFactory(new Callback<TableColumn<PhotoArea,String>, TableCell<PhotoArea,String>>() {
@Override
public TableCell<PhotoArea, String> call(TableColumn<PhotoArea, String> param) {
return new EditingCell();
}
});
col.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<PhotoArea,String>>() {
@Override
public void handle(CellEditEvent<PhotoArea, String> event) {
photoAreas.getSelectionModel().getSelectedItem().setDescription(event.getNewValue());
}
});
photoAreas.getColumns().add(col);
}
photoAreas.setEditable(true);
ContextMenu mCtx = new ContextMenu();
MenuItem mItem = new MenuItem("Remove");
mItem.setGraphic(new ImageView(new Image(getClass().getClassLoader().getResource("/icons/edit-delete.png").toExternalForm())));
mItem.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
PhotoArea area = photoAreas.getSelectionModel().getSelectedItem();
photoAreas.getItems().remove(area);
}
});
mCtx.getItems().add(mItem);
photoAreas.setContextMenu(mCtx);
ObservableList<PhotoArea> list = AdapterFactory.adapt(EMFProperties.list(PHOTO__AREAS).observeDetail(currentSelection));
photoAreas.setItems(list);
TitledPane areaProps = new TitledPane("Media Area Properties",photoAreas);
box.getChildren().add(areaProps);
VBox.setVgrow(areaProps, Priority.ALWAYS);
pane.setCenter(box);
}
@Inject
void setMedia(@Optional Media photo) {
currentSelection.setValue(photo);
}
@Focus
void focus() {
System.err.println("the focus is in the properties area");
}
@Inject
void setActivePhotoArea(@Optional PhotoArea area) {
if( area != null && photoAreas != null ) {
photoAreas.getSelectionModel().select(area);
}
}
static class EditingCell extends TableCell<PhotoArea, String> {
private TextField textField;
public EditingCell() {
}
@Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.selectAll();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()*2);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
}